"""
File: example_1.py
Project: 活动_1_制作飞机飞行动画
File Created: 2020/02/12 18:30:16
Author: Dunmore (fovd2020@outlook.com)
---------------------------------------------------------
Description:
1.3.1 活动2 完成飞机对战游戏的交互设计
①在活动1基础上，载入子弹的图片。
②移动我方飞机，子弹就会沿垂直方向飞出。
③敌机被子弹击中后爆炸。
④敌机被击中后再次随机地在屏幕上出现，随后重复第二步，直至用户退出游戏
---------------------------------------------------------
"""
import os
import pygame
from pygame.locals import Rect
from random import randint
import time

# 飞机移动速度
PLANE_SPEED = 20
# 子弹射程
SHOOT_RANGE = 200
# 飞机尺寸
PLANE_SIZE = 96
# 用到的填充颜色j
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

# 获取文件所在的路径
CURRRENT_DIR = (
    os.path.dirname(__file__) if "__file__" in locals() else os.getcwd()
)

# 初始化pygame
pygame.init()
# 设置窗口标题
pygame.display.set_caption("战斗机飞行")
# 创建一个Surface对象（面板，代表了在桌面上出现的那个窗口）
screen = pygame.display.set_mode([800, 600])
# 用自定义的白色填充
screen.fill(WHITE)
# 选择难度
choice_pic = pygame.image.load(
    os.path.join(CURRRENT_DIR, "images", "choice.png")
)
primary_pic = pygame.image.load(
    os.path.join(CURRRENT_DIR, "images", "hardchoiceprimary.jpg")
)
middle_pic = pygame.image.load(
    os.path.join(CURRRENT_DIR, "images", "hardchoicemiddle.jpg")
)
advanced_pic = pygame.image.load(
    os.path.join(CURRRENT_DIR, "images", "hardchoiceadvanced.jpg")
)
screen.blit(choice_pic, (163, 10))
pygame.display.update()
makechoice = True
hardchoice = 1
while makechoice:
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:
            cx = event.pos[0]
            cy = event.pos[1]
            if 11 <= cy <= 474:
                screen.fill(WHITE)
                if 173 <= cx <= 314:
                    hardchoice = 1
                    screen.blit(primary_pic, (300, 100))
                if 329 <= cx <= 470:
                    hardchoice = 3
                    screen.blit(middle_pic, (300, 100))
                if 486 <= cx <= 625:
                    hardchoice = 6
                    screen.blit(advanced_pic, (300, 100))
            makechoice = False
            pygame.display.update()
            time.sleep(2)


# 装载指定路径的图片(飞机)
my_flight = pygame.image.load(
    os.path.join(CURRRENT_DIR, "images", "type_3.png")
)
# 敌机
enemy = pygame.image.load(os.path.join(CURRRENT_DIR, "images", "enemy.png"))
# 子弹
bullet = pygame.image.load(os.path.join(CURRRENT_DIR, "images", "bullet.png"))
# 改变飞机大小为64x64
my_flight = pygame.transform.scale(my_flight, (PLANE_SIZE, PLANE_SIZE))
enemy = pygame.transform.scale(enemy, (PLANE_SIZE, PLANE_SIZE))
# 旋转敌机
enemy = pygame.transform.rotate(enemy, 180)
# 爆炸动画
Explosion_pic = pygame.image.load(
    os.path.join(CURRRENT_DIR, "images", "Explosion_2.png")
).convert_alpha()
explosion_imgs = [
    Explosion_pic.subsurface(Rect((i * 96, 0), (96, 96))) for i in range(12)
]
# 生命条
live_bar_pic = pygame.image.load(
    os.path.join(CURRRENT_DIR, "images", "livebar.jpg")
)
live_bar_pic = pygame.transform.scale(live_bar_pic, (500, 500))
live_bar_imgs = [
    live_bar_pic.subsurface(Rect((0, i * 45.5), (250, 35))) for i in range(11)
]


# 设定飞机出现的坐标(x,y)
my_x = 352
my_y = 500
# 设定敌机出现的位置
enemy_x = 100
enemy_y = 20

bullet_x = my_x
bullet_y = my_y

# 将图片绘制到screen上
screen.blit(my_flight, (my_x, my_y))
screen.blit(enemy, (enemy_x, enemy_y))
# TODO(Dunmore): 添加声音

# 刷新，将绘制上了飞机的screen重新显示
pygame.display.update()

# 载入计分模块
score_fighter = 0

nothit = False
is_first_time = True

# 创建时钟对象，可以控制游戏循环频率
t = pygame.time.Clock()

# 用来处理按键按住不放的情况,50ms响应时间
pygame.key.set_repeat(True, 50)

# 设置文字
score_string = f"你的得分是：{score_fighter}"
font = pygame.font.SysFont("SimHei", 24)
textft = font.render(score_string, True, BLACK)
textft_rect = textft.get_rect()
textft_rect.centerx = screen.get_rect().centerx
textft_rect.y = 18

# 设置爆炸区块
explosion_rect = (enemy_x - 16, enemy_y - 16, 126, 126)
# 是否显示爆炸动画
show_explosion = False
# 当前播放的爆炸动画帧
current_explosion_img = 0
# 初始化子弹当前离最大射程的距离
bullet_distance = 0
# 初始化子弹速度
bullet_speed = 5
# 初始化敌机速度
enemy_speed = 1
# 初始化生命值
life = 10

# 游戏结束标记，当按下Esc键的时候设置为False，不再继续循环
keep_going = True

while keep_going:
    # 获取事件响应
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            # 根据相应的方向按键调整x和y坐标来移动飞机
            if event.key in [pygame.K_UP, pygame.K_w]:
                my_y -= PLANE_SPEED
            if event.key in [pygame.K_DOWN, pygame.K_s]:
                my_y += PLANE_SPEED
            if event.key in [pygame.K_LEFT, pygame.K_a]:
                my_x -= PLANE_SPEED
            if event.key in [pygame.K_RIGHT, pygame.K_d]:
                my_x += PLANE_SPEED
            if event.key == pygame.K_ESCAPE:
                keep_going = False

    # 如果敌机超出屏幕范围，生命值-1,重置
    if 0 <= enemy_x <= 800 or 0 <= enemy_y <= 600:
        enemy_x += hardchoice * randint(1, enemy_speed)
        enemy_y += hardchoice * randint(1, enemy_speed)
    else:
        enemy_x = randint(0, 600)
        enemy_y = randint(0, 200)
        screen.blit(enemy, (enemy_x, enemy_y))
        score_fighter -= 10
        life -= 1

    if bullet_distance <= 0:
        bullet_y = my_y - 10
        bullet_x = my_x + PLANE_SIZE / 2 - 13.5
        bullet_distance = SHOOT_RANGE

    bullet_distance -= bullet_speed
    bullet_y -= bullet_speed

    # 重新绘制screen以及新的位置的飞机
    screen.fill(WHITE)
    screen.blit(my_flight, (my_x, my_y))
    screen.blit(bullet, (bullet_x, bullet_y))

    # 判断是否击中敌机
    if (
        enemy_x <= bullet_x <= enemy_x + PLANE_SIZE
        and enemy_y <= bullet_y <= enemy_y + PLANE_SIZE
        and (not show_explosion)
    ):
        # 敌机和子弹都消失
        dirty_rect = (enemy_x - 50, enemy_y - 50, 200, 200)
        screen.fill(WHITE, dirty_rect)
        pygame.display.update(dirty_rect)

        score_fighter += 10
        # 设置显示爆炸场景动画的标志
        show_explosion = True

    if show_explosion:
        screen.fill(WHITE, explosion_rect)
        screen.blit(explosion_imgs[current_explosion_img], (enemy_x, enemy_y))
        if current_explosion_img == 11:
            show_explosion = False
            current_explosion_img = 0
            enemy_x = randint(0, 600)
            enemy_y = randint(0, 200)
            screen.blit(enemy, (enemy_x, enemy_y))
            time.sleep(0.2)
        else:
            current_explosion_img += 1
    else:
        screen.blit(enemy, (enemy_x, enemy_y))

    # 刷新生命条
    screen.blit(live_bar_imgs[life], (10, 10))

    # 如果生命值耗尽，设置退出游戏标记并设置显示文字
    if life <= 0:
        keep_going = False
        score_string = f"你的得分是：{score_fighter}>>>游戏结束"
    else:
        score_string = f"你的得分是：{score_fighter}"

    # 刷新文字
    textft = font.render(score_string, True, BLACK)
    screen.blit(textft, textft_rect)

    # 刷新显示
    pygame.display.update()

    # 设定每秒循环30次
    t.tick(30)

# 停留2秒后退出游戏
time.sleep(2)
pygame.quit()
